const CryptoJS = require("rc4.js");

var Bluetooth = {};
var rssi;
var deviceId;
var serviceId;
var connectedDeviceId;
var notify_id;
var characteristicId;
var read_id;
var openDeviceName;
var keyMd5 = 'SK1234567890';

Bluetooth.ConnectTo = function (deviceName, deviceID, callBack) {
  // Bluetooth.ConnectTo = function (callBack) {
  var self = this
  if (deviceID) {
    openDeviceName = deviceName; //名字
    deviceId = deviceID;
    // wx.closeBluetoothAdapter({});
    // wx.openBluetoothAdapter({});
    // wx.stopBluetoothDevicesDiscovery({});
    // wx.onBluetoothAdapterStateChange(function (res) { });

    wx.closeBluetoothAdapter({
      complete: function (res) {
        console.log(res)
        wx.openBluetoothAdapter({
          success: function (res) {
            console.log(res)
            wx.getBluetoothAdapterState({
              success: function (res) {

                wx.createBLEConnection({
                  deviceId: deviceId,
                  success: function (res) {
                    console.log("连接成功");
                    self.getService(callBack);
                  },
                  fail: function (res) {
                    console.log(res)
                    wx.hideLoading()
                    wx.showModal({
                      title: '提示',
                      content: '连接失败',
                      showCancel: false
                    })
                  }
                })
              }
            })
          }
        })
      }
    })
  } else {
    wx.stopBluetoothDevicesDiscovery({});
    wx.createBLEConnection({
      deviceId: deviceId,
      success: function (res) {
        self.getService(callBack);
      },
      fail: function (res) {
        console.log(res)
        wx.hideLoading()
        wx.showModal({
          title: '提示',
          content: '连接失败',
          showCancel: false
        })
      }
    })
  }


}
// 延时操作
Bluetooth.timedMsg = function (callBack) {
  var self = this
  setTimeout(function () {
    if (deviceId == null) {
      self.stopDevices(callBack);
    }
  }, 1000);
}

Bluetooth.stopDevices = function (callBack) {
  wx.stopBluetoothDevicesDiscovery({
    success: function (res) {
      callBack({
        state: "002",
        mac: "nil"
      });
    },
    fail: function (res) {

    }
  })
}

Bluetooth.getService = function (callBack) {
  var self = this

  // 监听蓝牙连接
  wx.onBLEConnectionStateChange(function (res) {
    console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`);
  });
  // 获取蓝牙设备service值
  wx.getBLEDeviceServices({
    deviceId: deviceId,
    success: function (res) {

      console.log("获取服务特性", res);

      serviceId = openDeviceName?.length > 7 ? res.services[0].uuid : res.services[1].uuid;
      // 获取服务的特性
      self.getCharacter(callBack);
    }
  })
}

// 获取服务的特性
Bluetooth.getCharacter = function (callBack) {
  var self = this
  wx.getBLEDeviceCharacteristics({
    deviceId: deviceId,
    serviceId: serviceId,
    success: function (res) {
      console.log('res');
      console.log("2222222", res);
      for (let i = 0; i < res.characteristics.length; i++) {
        let charc = res.characteristics[i];
        if (charc.properties.notify) {
          notify_id = charc.uuid;
          if (charc.properties.write) {
            characteristicId = charc.uuid;
          }
          if (charc.properties.write) {
            read_id = charc.uuid;
          }
        }
      }


      console.log("notify_id:11", notify_id);
      wx.notifyBLECharacteristicValueChange({
        state: true,
        deviceId: deviceId,
        serviceId: serviceId,
        characteristicId: notify_id,
        success: function (res) {
          console.log("订阅成功");
          setTimeout(function () {
            // 发送命令
            self.pushNot(callBack);
          }, 500);
          // 读取回调消息
          self.onNotifyChange(callBack);
        }
      })
    },
    fail: function (res) {
      // fail
      console.log("获取服务的特性失败");
    },
    complete: function (res) {
      // complete
    }
  }, 2000)
},



  // 发送命令
  Bluetooth.pushNot = function (callBack) {
    var self = this;
    let buf
    if (openDeviceName.length > 7) {
      const card = 0xA1B2C3D4
      let encryStr = CryptoJS.RC4.encrypt("[" + card + "," + "All_ViewId" + ",," + getExpryTime() + ",0,0," + "A" + ",]", CryptoJS.enc.Utf8.parse(keyMd5)).toString().toLocaleUpperCase()
      buf = self.str2ab(JSON.stringify({ "O": "OpenDoor", "D": "CB01" + encryStr }))
      console.log("encryStr加密字符串", encryStr);
    } else {
      buf = self.str2ab(JSON.stringify({
        "ViewId": "V123",
        "CmdCode": 1
      }));
    }
    console.warn("-------", openDeviceName.length, buf)
    writeBleTooth(buf);
  }

function writeBleTooth(buf) {
  wx.writeBLECharacteristicValue({
    deviceId: deviceId,
    serviceId: serviceId,
    characteristicId: characteristicId,
    value: buf,
    success: function (res) {
      console.log("success  指令发送成功");
    },
    fail: function (res) {
      console.log("指令发送失败");
    },
    complete: function (res) { }
  })
}
function getExpryTime(params) {
  let currentDate = new Date();
  let newDate = new Date(currentDate.getTime() + 10 * 60000); // 10分钟后的时间
  let year = newDate.getFullYear();
  let month = (newDate.getMonth() + 1).toString().padStart(2, '0');
  let day = newDate.getDate().toString().padStart(2, '0');
  let hours = newDate.getHours().toString().padStart(2, '0');
  let minutes = newDate.getMinutes().toString().padStart(2, '0');
  let seconds = newDate.getSeconds().toString().padStart(2, '0');

  let formattedDate = year + month + day + hours + minutes + seconds;

  return formattedDate
}
// 读取蓝牙返回值
//监听消息
Bluetooth.onNotifyChange = function (callBack) {
  console.log("开始读取返回值")
  var self = this;
  wx.onBLECharacteristicValueChange(function (res) {
    console.log("1221221", String.fromCharCode.apply(null, new Uint8Array(res.value)), res.value)
    try {
      const msg = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(res.value)))
      console.log("收到返回值", msg);
      if (msg?.CmdCode && msg.CmdCode == 1) {
        const randomNumber = msg.CmdParams[0].Random
        const ViewId = msg.ViewId
        const card = 0xA1B2C3D4
        var z16 = parseInt(card).toString(16);
        const zlength = z16.length
        for (var i = 0; i < 16 - zlength; i++) {
          z16 = '0' + z16
        }
        console.log(z16);
        //RC4数据加密

        var encrypted = CryptoJS.RC4.encrypt(randomNumber + z16, CryptoJS.enc.Utf8.parse(keyMd5)).toString()
        const data = JSON.stringify({
          ViewId,
          CmdCode: 2,
          CmdParams: [{
            BTData: encrypted,
          }]
        })
        console.log(data);
        let buf = self.str2ab(data);
        writeBleTooth(buf);
      } else {
        if (msg.CmdStatus == 1 || (msg.S == 1)) {
          callBack({
            "state": "OK",
            "mac": openDeviceName
          })
        } else {
          callBack({
            state: "NO",
            mac: openDeviceName
          })
        }
        closeBluetooth();
      }
    } catch (e) {
      closeBluetooth();
      callBack({
        state: "NO",
        mac: openDeviceName
      })
    }
  })
}

function closeBluetooth() {
  wx.closeBluetoothAdapter({
    success: function (res) {
      console.log("断开蓝牙成功")
    }
  })
}

// 转换
Bluetooth.str2ab = function (str) {
  var buf = new ArrayBuffer(str.length);
  var bufView = new Uint8Array(buf);
  for (var i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

Bluetooth.str2abInbleX = function (str) {
  var buf = new ArrayBuffer(str.length);
  var bufView = new Uint16Array(buf);
  for (var i = 0; i < str.length; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

Bluetooth.ab2str = function ab2str(buf) {
  return String.fromCharCode.apply(null, new Uint8Array(buf));
}

//十六进制字符串转字节数组
function Str2Bytes(str) {
  var pos = 0;
  var len = str.length;
  if (len % 2 != 0) {
    return null;
  }
  len /= 2;
  var hexA = new Array();
  for (var i = 0; i < len; i++) {
    var s = str.substr(pos, 2);
    var v = parseInt(s, 16);
    hexA.push(v);
    pos += 2;
  }
  let arrayBuffer = new Uint8Array(hexA).buffer;
  return arrayBuffer;
}

//字节数组转十六进制字符串，对负值填坑
function Bytes2HexString(buffer) {
  return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}


function random() {
  let array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
  var randomStr = "";
  for (var i = 0; i < 8; i++) {
    var a = Math.floor(Math.random() * 15);
    randomStr += array[a];
  }
  return randomStr;
}


module.exports = Bluetooth;